<script setup>
import { ref } from "vue";
import { nextTick } from "vue";
import ChannelSelect from "@/views/article/components/ChannelSelect.vue";
import { Plus } from "@element-plus/icons-vue";
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css';
import { artPublishService, artGetDetailService, artEditService } from "@/api/article";
import { ElMessage } from "element-plus";
import axios from "axios";

const prop = defineProps({
  title: String
})

const emit = defineEmits(['success'])
// 表单校验
const rules = {
  title: [{
    required: true, message: '请填写文章标题', trigger: 'blur'
  }],
  cateId: [{
    required: true, message: '请选择文章类型', trigger: 'blur'
  }],
  // coverImg: [{
  //   required: true, message: '请选择文章图片', trigger: 'blur'
  // }, {
  //   validator: (rule, value, callback) => {
  //     if (value === null || value === "")
  //       callback(new Error("请选择文章图片"))
  //     if (formModel.value.coverImg === '' || formModel.value.coverImg === null)
  //       callback(new Error("请选择文章图片"))
  //     callback()
  //   }
  // }]
  coverImg: [{
    required: true,
    message: '请选择文章图片',
    trigger: 'change'  // 改为change触发，因为文件选择是change事件
  }],
  content: [{
    required: true, message: '请输入文章内容', trigger: 'blur'
  },
  {
    validator: (rule, value, callback) => {
      // 移除HTML标签后检查是否还有实际内容
      const text = value.replace(/<[^>]+>/g, '').trim();
      if (!text) {
        callback(new Error('文章内容不能为空'));
      } else {
        callback();
      }
      if (!formModel.value.content.replace(/<[^>]+>/g, '').trim()) {
        callback(new Error('文章内容不能为空'));

      }
      else {
        callback();
      }
    },
    trigger: 'change'
  }
  ]
}
// 控制抽屉显示隐藏
const visibleDrawer = ref(false)
const editorRef = ref();
const open = async (row) => {
  visibleDrawer.value = true

  if (row.id) {
    console.log("编辑回显");
    const res = await artGetDetailService(row.id)
    formModel.value = res.data
    // 图片单独处理
    imgUrl.value = res.data.imgUrl
    // 注意：提交给后台，需要的数据格式，是file对象格式
    // 需要将图片网络地址=>变为file对象,存储起来
    formModel.value.coverImg = await imageUrlToFileObject(imgUrl.value, 'image')

  } else {
    formModel.value = {
      ...defaultForm, //基于默认的数据重置表单

    }
    // 需要手动重置图片上传和富文本编辑器
    imgUrl.value = null
    nextTick(() => {
      if (editorRef.value) {
        editorRef.value.setHTML('');
      }
    })
    // console.log("添加");
  }
  console.log(row);
}
defineExpose({
  open
})
const defaultForm = {
  title: '',
  cateId: '',
  coverImg: null,
  content: '',
  state: ''
}
// 准备数据
const formModel = ref({
  ...defaultForm
})
// 图片上传
const imgUrl = ref("")
const onSelectFile = (uploadFile) => {
  // console.log(uploadFile);
  imgUrl.value = URL.createObjectURL(uploadFile.raw)
  console.log(imgUrl.value);
  formModel.value.coverImg = uploadFile.raw
}

// 提交文章
const onPublish = async (state) => {
  if (formModel.value.title === '' || formModel.value.content === '')
    return ElMessage.error("请填写文章")
  // 将文章发表状态存入formModel
  formModel.value.state = state
  // 由于后端要求formData对象，所以将普通对象转换为formData对象
  // const fd = new FormData()
  // for (let key in formModel.value) {
  //   fd.append(key, formModel.value[key])
  // }
  // 创建FormData对象
  const fd = new FormData();
  fd.append('title', formModel.value.title);
  fd.append('cateId', formModel.value.cateId);
  fd.append('content', formModel.value.content);
  fd.append('state', formModel.value.state);

  // 只有选择了图片时才添加coverImg字段
  if (formModel.value.coverImg) {
    fd.append('coverImg', formModel.value.coverImg);
  }
  // 发请求
  if (formModel.value.id) {
    // console.log("编辑操作");
    await artEditService(fd)
    ElMessage.success("修改成功")
    visibleDrawer.value = false
    emit('success', 'edit')
  } else {
    await artPublishService(fd)
    ElMessage.success("添加成功")
    visibleDrawer.value = false
    // 通知到父组件，添加成功了
    emit('success', 'add')
  }
}

// 要将网络图片地址转换为File对象的函数
async function imageUrlToFileObject(imageUrl, filename) {
  try {
    const response = await axios({
      method: 'get',
      url: imageUrl,
      responseType: 'blob'
    })
    // 从响应头获取内容类型
    const contentType = response.headers['content-type'] || 'image/png';

    // 提取文件扩展名
    const extension = contentType.split('/')[1] || 'png';
    // 创建File对象
    const file = new File([response.data], filename || `image.${extension}`, { type: contentType });
    return file;
  } catch (error) {
    console.error('转换失败:', error);
    throw new Error('图片转换失败: ' + error.message);
  }
}
</script>

<template>
  <!-- 抽屉组件 -->
  <el-drawer v-model="visibleDrawer" :title=title size="50%">
    <el-form :model="formModel" label-width="100px" :rules="rules">
      <el-form-item label="文章标题" prop="title">
        <el-input v-model="formModel.title" placeholder="请输入标题"></el-input>
      </el-form-item>
      <el-form-item label="文章分类" class="edit" prop="cateId">
        <ChannelSelect v-model="formModel.cateId" width="100%"></ChannelSelect>
      </el-form-item>
      <el-form-item label="文章封面" prop="coverImg">
        <!-- 此处需要关闭element-plus的自动上传，不需要配置action等参数
      只需要做前端的本地预览图片即可，无需在提交前上传图片
      语法:URL.createOjbectURL(...)创建本地预览的地址，来预览
      -->
        <el-upload class="avatar-uploader" :show-file-list="false" :auto-upload="false" :on-change="onSelectFile">
          <img :src="imgUrl" v-if="imgUrl" class="avatar">
          <el-icon v-else class="avatar-uploader-icon">
            <Plus />
          </el-icon>
        </el-upload>
      </el-form-item>
      <el-form-item label="文章内容" prop="content">
        <div class="editor">
          <QuillEditor ref="editorRef" theme="snow" v-model:content="formModel.content" content-type="html">
          </QuillEditor>
        </div>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onPublish('已发布')">发表</el-button>
        <el-button type="info" @click="onPublish('草稿')">草稿</el-button>
      </el-form-item>
    </el-form>
  </el-drawer>
</template>
<style scoped>
:deep(.edit .el-tooltip__trigger) {
  width: 655px;
}

.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}

.editor {
  width: 100%;
}

:deep(.ql-editor) {
  min-height: 200px;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
